Allocating Memory

The routine arena_getmem(n) returns a pointer to (at least) n bytes of memory. Note that n is rounded up to ensure that returned pointers are always aligned. We align to the nearest 8 byte segment, since that'll satisfy the more common 2-byte and 4-byte alignment restrictions too.

@o arena.c @void *arena_getmem(n) size_t n; char *q; char *p = arena->avail; n = (n + 7) & 7; /* ensuring alignment to 8 bytes */ q = p + n; if (q <= arena->limit) arena->avail = q; return p; @<Find a new chunk of memory@> @| arena_getmem @

If the current chunk doesn't have adequate space (at least n bytes) we examine the rest of the list of chunks (starting at arena->next) looking for a chunk with adequate space. If n is very large, we may not find it right away or we may not find a suitable chunk at all. @d Find a new chunk... @ Chunk *ap = arena; Chunk *np = ap->next; while (np) char *v = sizeof(Chunk) + (char *) np; if (v + n <= np->limit) np->avail = v + n; arena = np; return v; ap = np; np = ap->next; @<Allocate a new chunk of memory@> @

If there isn't a suitable chunk of memory on the free list, then we need to allocate a new one. @d Allocate a new ch... @ size_t m = n + 10000; np = (Chunk *) malloc(m); np->limit = m + (char *) np; np->avail = n + sizeof(Chunk) + (char *) np; np->next = NULL; ap->next = np; arena = np; return sizeof(Chunk) + (char *) np; @